package com.wss.lsl.test.driven.scoketio.selector;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;

public class TimeServerSelector {

	public static void main(String[] args) throws Exception {
		ServerSocketChannel ssc = ServerSocketChannel.open();
		Selector s = Selector.open();
		ssc.configureBlocking(false);
		InetSocketAddress local8888 = new InetSocketAddress(8888);
		ssc.bind(local8888);
		ssc.register(s, SelectionKey.OP_ACCEPT);

		int addedKey = 0;
		ByteBuffer bb = ByteBuffer.allocate(1024);
		while (true) {
			addedKey = s.select();
			// select()阻塞的方法，等待客户端的请求。
			System.out.println("addedKey: " + addedKey);
			// 每次返回的都是同一个实例，清空了才可以继续加key?
			Set<SelectionKey> skeys = s.selectedKeys();
			Iterator<SelectionKey> iterKey = skeys.iterator();
			while (iterKey.hasNext()) {
				SelectionKey sk = iterKey.next();
				System.out.println("before isAcceptable");
				// 从SelectionKey中获取连接信息
				if (sk.isAcceptable()) {
					System.out.println("after isAcceptable");

					ServerSocketChannel serverSocketChannel = (ServerSocketChannel) sk
							.channel();
					serverSocketChannel.configureBlocking(false);
					SocketChannel sc = serverSocketChannel.accept();
					sc.configureBlocking(false);
					sc.register(s, SelectionKey.OP_WRITE);
				} else if(sk.isWritable()) {
					SocketChannel client = (SocketChannel) sk
							.channel();
					client.configureBlocking(false);
					
					bb.put(new Date().toString().getBytes("UTF-8"));
					bb.flip();
					client.write(bb);
					bb.clear();
					
					client.register(s, SelectionKey.OP_READ);
				} else if(sk.isReadable()) {
					SocketChannel client = (SocketChannel)sk.channel();
					client.configureBlocking(false);
					
					// clear不像我想象中那样工作。
					System.out.println(new String(bb.array()));
					// 实际的读取字节要以返回的数字为准
					int count = client.read(bb);
					bb.flip();
					System.out.println("read: " + new String(bb.array(), 0, count));
					bb.clear();
					
					client.register(s, SelectionKey.OP_WRITE);
				}
			}

			// 为什么要清除SelectionKey。才可以处理第2个、3个客户端请求。
			skeys.clear();
		}
		
		// System.out.println("addedKey: " + addedKey);
	}
}
